package jumpingnotes.tool;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

public class CodeGenerator
{
	private static final String pattern_file = "src/jumpingnotes/tool/Pattern.txt";

	private String src;
	private String dest;
	private String text;
	private String result;
	private String classPlaceholder = "%%";
	private String variablePlaceholder = "%_%";
	private String[] classPatterns;
	private String[] variablePatterns;

	public CodeGenerator(String src, String dest)
	{
		this.src = src;
		this.dest = dest;
	}

	public void loadPatterns() throws IOException
	{
		BufferedReader reader = null;
		try
		{
			reader = new BufferedReader(new FileReader(pattern_file));
			List<String> classPatternList = new ArrayList<String>();
			List<String> variablePatternList = new ArrayList<String>();

			String className = reader.readLine();
			while (className != null)
			{
				classPatternList.add(className);
				String variableName = classNameToVariableName(className);
				variablePatternList.add(variableName);
				className = reader.readLine();
			}

			classPatterns = classPatternList.toArray(new String[0]);
			variablePatterns = variablePatternList.toArray(new String[0]);
		}
		finally
		{
			if (reader != null)
				reader.close();
		}
	}

	private String classNameToVariableName(String className)
	{
		if (className == null || className.length() == 0)
			return null;

		// change the first letter to lower case
		char upperCaseLetter = className.charAt(0);
		char lowerCaseLetter = Character.toLowerCase(upperCaseLetter);

		String variableName = lowerCaseLetter + className.substring(1);
		return variableName;
	}

	public void loadText() throws IOException
	{
		BufferedReader reader = null;
		try
		{
			reader = new BufferedReader(new FileReader(src));
			StringBuilder builder = new StringBuilder();

			String line = reader.readLine();
			while (line != null)
			{
				builder.append(line);
				builder.append("\n");
				line = reader.readLine();
			}

			text = builder.toString();
		}
		finally
		{
			if (reader != null)
				reader.close();
		}
	}

	public void saveResult() throws IOException
	{
		PrintWriter writer = null;
		try
		{
			writer = new PrintWriter(new FileWriter(dest));
			writer.print(result);
		}
		finally
		{
			if (writer != null)
				writer.close();
		}
	}

	public void generate()
	{
		StringBuilder resultBuilder = new StringBuilder();

		String[] partTexts = text.split("----\n");

		for (String partText : partTexts)
		{
			String partResult;

			if (partText.indexOf(classPlaceholder) >= 0 || partText.indexOf(variablePlaceholder) >= 0)
			{
				partResult = generatePart(partText);
			}
			else
			{
				partResult = partText;
			}

			resultBuilder.append(partResult);
		}

		result = resultBuilder.toString();
	}

	private String generatePart(String partText)
	{
		StringBuilder partResult = new StringBuilder();
		for (int i = 0; i < classPatterns.length; i++)
		{
			String partPattern = partText;
			partPattern = partPattern.replaceAll(classPlaceholder, classPatterns[i]);
			partPattern = partPattern.replaceAll(variablePlaceholder, variablePatterns[i]);
			partResult.append(partPattern);
		}
		return partResult.toString();
	}

	public static void main(String[] args)
	{
		String sourceFolder = "src/";
		String[] name = { "AccessService.java", "AccessServiceImpl.java", "applicationContext.xml", "XxxDao",
				"XxxHibernateDao" };
		String[] src = { "jumpingnotes/tool/AccessService.java.template",
				"jumpingnotes/tool/AccessServiceImpl.java.template",
				"jumpingnotes/tool/applicationContext.xml.template", "jumpingnotes/tool/XxxDao.template",
				"jumpingnotes/tool/XxxHibernateDao.template" };
		String[] dest = { "jumpingnotes/service/AccessService.java", "jumpingnotes/service/AccessServiceImpl.java",
				"applicationContext.xml", "jumpingnotes/dao/XxxDao", "jumpingnotes/dao/hibernate/XxxHibernateDao" };

		for (int i = 0; i < name.length; i++)
		{
			try
			{
				System.out.println("Generating " + name[i] + "...");
				CodeGenerator cg = new CodeGenerator(sourceFolder + src[i], sourceFolder + dest[i]);
				cg.loadPatterns();
				cg.loadText();
				cg.generate();
				cg.saveResult();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
		}
	}
}
